package com.kgis.map.control {
   import flash.events.MouseEvent;
   import flash.text.TextField;
   import flash.text.TextFormat;
   import com.kgis.map.geometry.basetype.Location;
   import com.kgis.map.geometry.basetype.Pixel;
   import com.kgis.map.events.MapEvent;
   import com.kgis.map.Map;
   import com.kgis.map.projection.Projection;
   import com.kgis.map.control.Control;

   /**
    * 控件显示鼠标当前的地图坐标
    */
   public class MousePosition extends Control {
      /**
       * Texfield wich displays coordinates
       */
      private var _label:TextField = null;
      private var _labelFormat:TextFormat = null;
      /**
       * Text before coordinates in the label, which doesn't change.
       */
      private var _prefix:String = "";

      /**
       * the caracter between the lon and the lat
       */
      private var _separator:String = ", ";

      /**
       * Text after coordinates in the label, which doesn't change.
       */
      private var _suffix:String = "";

      private var _numdigits:Number = 5;

      private var _granularity:int = 10;

      private var _lastXy:Pixel = null;

      /**
       * The projection display in the label
       */
      [Bindable]
      private var _displayProjection:Projection = null;

      /**
       * MousePosition Constructor
       *
       * @param position
       */
      public function MousePosition(position:Pixel = null) {
         super(position);

         this.label = new TextField();
         this.label.width = 250;

         _labelFormat = new TextFormat();
         _labelFormat.size = 12;
         _labelFormat.color = 0x000000;
         _labelFormat.font = "微软雅黑";
         this.label.defaultTextFormat = _labelFormat ;

      }

      override public function draw():void {
         super.draw();
         this.addChild(label);
         this.redraw();
      }

      /**
       * Display the coordinate where is the mouse
       *
       * @param evt
       */
      public function redraw(evt:MouseEvent = null):void {
         var lonLat:Location;

         if (evt != null) {
            if (this.lastXy == null || Math.abs(map.mouseX - this.lastXy.x) > this.granularity || Math.abs(map.mouseY - this.lastXy.y) > this.granularity) {
               this.lastXy = new Pixel(map.mouseX, map.mouseY);
               return;
            }
            this.lastXy = new Pixel(map.mouseX, map.mouseY);
            lonLat = this.map.getLocationFromMapPx(this.lastXy);
         }

         if (lonLat == null) {
            lonLat = new Location(0, 0);
         }

         if (this._displayProjection) {
            lonLat = lonLat.reprojectTo(this.map.projection,this._displayProjection);
         }

         var digits:int = int(this.numdigits);
         var currentBaseLayerUnits:String = this.map.projection.projParams.units;
         if(currentBaseLayerUnits == "m"){
            digits = int(this.numdigits);
         }
         else
         {
            digits = int(this.numdigits)+3;
         }

         this.label.text = this.prefix + lonLat.lon.toFixed(digits) + this.separator + lonLat.lat.toFixed(digits) + this.suffix;
      }

      override public function set map(map:Map):void {
         if (this.map) {
            this.map.removeEventListener(MouseEvent.MOUSE_MOVE, this.redraw);
            this.map.removeEventListener(MapEvent.DRAG_START, this.deactivateDisplay);
            this.map.removeEventListener(MapEvent.MOVE_END, this.activateDisplay);
         }

         super.map = map;

         if (this.map) {
            this.map.addEventListener(MouseEvent.MOUSE_MOVE, this.redraw);
            this.map.addEventListener(MapEvent.DRAG_START, this.deactivateDisplay);
            this.map.addEventListener(MapEvent.MOVE_END, this.activateDisplay);
         }
      }

      /**
       * Stop the update of coordinates. Useful while paning the map.
       *
       * @param event
       */
      private function deactivateDisplay(event:MapEvent):void {
         this.map.removeEventListener(MouseEvent.MOUSE_MOVE, this.redraw);
      }

      /**
       * Start the update of coordinates.
       *
       * @param event
       */
      private function activateDisplay(event:MapEvent):void {
         this.map.addEventListener(MouseEvent.MOUSE_MOVE, this.redraw);
      }

      /**
       * Getters &amp; setters
       */
      public function get prefix():String {
         return _prefix;
      }

      public function set prefix(value:String):void {
         _prefix = value;
      }

      public function get separator():String {
         return _separator;
      }

      public function set separator(value:String):void {
         _separator = value;
      }

      public function get suffix():String {
         return _suffix;
      }

      public function set suffix(value:String):void {
         _suffix = value;
      }

      public function get numdigits():Number {
         return _numdigits;
      }

      public function set numdigits(value:Number):void {
         _numdigits = value;
      }

      public function get granularity():int {
         return _granularity;
      }

      public function set granularity(value:int):void {
         _granularity = value;
      }

      public function get lastXy():Pixel {
         return _lastXy;
      }

      public function set lastXy(value:Pixel):void {
         _lastXy = value;
      }

      public function get displayProjection():Projection {
         return _displayProjection;
      }

      public function set displayProjection(value:Projection):void {
         _displayProjection = value;
      }

      public function get label():TextField {
         return this._label;
      }

      public function set label(value:TextField):void {
         this._label = value;
      }

      public function get labelFormat():TextFormat
      {
         return _labelFormat;
      }

      public function set labelFormat(value:TextFormat):void
      {
         _labelFormat = value;
         this.label.defaultTextFormat = _labelFormat ;
      }

   }
}
